# tts/tts_manager.py
# TTS管理器，负责流式TTS的主要逻辑和协调

import asyncio
import threading
import time
from typing import AsyncGenerator, Optional

from .tts_client import TTSClient
from .tts_audio import AudioPlayer, AudioQueueManager


class StreamingTTS:
    """
    流式TTS处理器
    协调TTS客户端、音频播放器和流处理逻辑
    """
    
    def __init__(self, config: dict):
        self.config = config
        
        # 初始化组件
        self.tts_client = TTSClient(
            api_host=config["API_HOST"],
            tts_url=config["TTS_URL"],
            control_url=config["CONTROL_URL"]
        )
        
        self.audio_player = AudioPlayer(config["SAMPLE_RATE"])
        self.queue_manager = AudioQueueManager(self.audio_player)
        
        # 状态管理
        self.is_processing = False
        self.stop_event = threading.Event()
        self.is_tts_available = True  # TTS服务可用性状态
        
        # 延迟测量
        self.user_input_time = 0
        self.llm_first_sentence_time = 0
    
    def set_user_input_time(self, t0_time: float):
        """设置用户输入时间"""
        self.user_input_time = t0_time
    
    def check_tts_availability(self) -> bool:
        """检查TTS服务可用性"""
        self.is_tts_available = self.tts_client.check_connection()
        return self.is_tts_available
    
    def interrupt(self):
        """中断当前处理"""
        print("\n[系统] 正在中断TTS处理...")
        # 立即设置停止标志
        self.stop_event.set()
        
        # 发送硬中断命令
        if self.is_tts_available:
            self.tts_client.send_stop_command()
        
        # 如果正在处理，准备新任务
        if self.is_processing:
            self._interrupt_and_prepare_new_task()
    
    def _interrupt_and_prepare_new_task(self):
        """中断旧任务并准备新任务"""
        # 设置停止信号
        self.stop_event.set()
        
        # 发送硬中断命令
        self.tts_client.send_stop_command()
        
        # 准备新任务
        new_gen_id = self.queue_manager.interrupt_and_prepare_new_task()
        
        # 清除停止标志
        self.stop_event.clear()
        
        return new_gen_id
    
    def _clean_text_for_tts(self, text: str) -> str:
        """清理文本，去除表情符号和其他非文本字符"""
        import re
        
        # 去除表情符号 (Unicode范围)
        # 基本表情符号: U+1F600-U+1F64F
        # 符号和象形文字: U+1F300-U+1F5FF  
        # 交通和地图符号: U+1F680-U+1F6FF
        # 杂项符号: U+1F700-U+1F77F
        # 装饰符号: U+1F780-U+1F7FF
        # 补充符号和象形文字: U+1F800-U+1F8FF
        # 表情符号: U+1F900-U+1F9FF
        # 补充符号和象形文字: U+1FA00-U+1FA6F
        # 符号和象形文字扩展-A: U+1FA70-U+1FAFF
        # 表情符号修饰符: U+1F3FB-U+1F3FF
        # 表情符号连接符: U+200D
        # 变体选择器: U+FE0F
        emoji_pattern = re.compile(
            "["
            "\U0001F600-\U0001F64F"  # 表情符号
            "\U0001F300-\U0001F5FF"  # 符号和象形文字
            "\U0001F680-\U0001F6FF"  # 交通和地图符号
            "\U0001F700-\U0001F77F"  # 杂项符号
            "\U0001F780-\U0001F7FF"  # 装饰符号
            "\U0001F800-\U0001F8FF"  # 补充符号和象形文字
            "\U0001F900-\U0001F9FF"  # 表情符号
            "\U0001FA00-\U0001FA6F"  # 补充符号和象形文字
            "\U0001FA70-\U0001FAFF"  # 符号和象形文字扩展-A
            "\U0001F3FB-\U0001F3FF"  # 表情符号修饰符
            "\U0000200D"             # 表情符号连接符
            "\U0000FE0F"             # 变体选择器
            "]+", 
            flags=re.UNICODE
        )
        
        # 去除表情符号
        cleaned_text = emoji_pattern.sub('', text)
        
        # 去除其他特殊字符，但保留标点符号
        # 去除控制字符、零宽字符等
        cleaned_text = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]', '', cleaned_text)
        
        # 去除多余的空白字符
        cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
        
        return cleaned_text

    def _smart_sentence_split(self, text: str) -> list:
        """智能句子分割，优化首句延迟和音频质量，特别优化英文处理"""
        if not text.strip():
            return []
        
        # 先清理文本
        cleaned_text = self._clean_text_for_tts(text)
        if not cleaned_text.strip():
            return []
        
        # 检测文本语言类型
        is_english = self._is_english_text(cleaned_text)
        
        if is_english:
            return self._split_english_text(cleaned_text)
        else:
            return self._split_chinese_text(cleaned_text)
    
    def _is_english_text(self, text: str) -> bool:
        """检测文本是否为英文"""
        # 统计中英文字符数量
        chinese_chars = sum(1 for char in text if '\u4e00' <= char <= '\u9fff')
        english_chars = sum(1 for char in text if char.isalpha() and ord(char) < 128)
        
        # 如果英文字符明显多于中文字符，认为是英文
        return english_chars > chinese_chars * 2
    
    def _split_english_text(self, text: str) -> list:
        """英文文本智能分割，优化长度控制"""
        sentences = []
        current_sentence = ""
        
        # 英文句子结束符
        sentence_endings = ['.', '!', '?']
        # 英文短语分隔符
        phrase_separators = [',', ';', ':', '—', '–']
        
        # 更严格的长度限制，优化TTS处理
        max_sentence_length = 60   # 减少到60字符，更快处理
        max_phrase_length = 40     # 减少到40字符，更快分割
        min_sentence_length = 8    # 最小长度
        
        i = 0
        while i < len(text):
            char = text[i]
            current_sentence += char
            
            # 检查句子结束符
            if char in sentence_endings:
                # 检查是否在缩写中（如 Mr., Dr., etc.）
                if self._is_abbreviation(text, i):
                    i += 1
                    continue
                
                # 检查句子长度
                if len(current_sentence.strip()) >= min_sentence_length:
                    sentences.append(current_sentence.strip())
                    current_sentence = ""
                i += 1
                continue
            
            # 检查短语分隔符 - 更积极的分割
            elif char in phrase_separators:
                # 如果当前句子已经达到短语长度限制，立即分割
                if len(current_sentence) >= max_phrase_length:
                    sentences.append(current_sentence.strip())
                    current_sentence = ""
                i += 1
                continue
            
            # 更频繁的长度检查
            elif len(current_sentence) >= max_sentence_length:
                # 尝试在最近的合适分割点分割
                split_point = self._find_best_split_point(current_sentence, max_sentence_length)
                if split_point > 0:
                    sentences.append(current_sentence[:split_point].strip())
                    current_sentence = current_sentence[split_point:].strip()
                else:
                    # 强制分割
                    sentences.append(current_sentence.strip())
                    current_sentence = ""
            
            i += 1
        
        # 处理剩余文本
        if current_sentence.strip():
            if len(current_sentence.strip()) >= min_sentence_length:
                sentences.append(current_sentence.strip())
            elif sentences:  # 如果太短，合并到最后一个句子
                sentences[-1] += " " + current_sentence.strip()
        
        # 如果只有一个句子，检查是否需要进一步分割
        if len(sentences) == 1 and len(sentences[0]) > max_sentence_length:
            return self._force_split_long_sentence(sentences[0])
        
        return sentences if sentences else [text.strip()]
    
    def _split_chinese_text(self, text: str) -> list:
        """中文文本智能分割，优化表情符号处理"""
        # 主要句子结束符
        main_endings = ['。', '！', '？']
        # 次要句子结束符
        minor_endings = ['；', '：', '，']
        
        sentences = []
        current_sentence = ""
        
        for char in text:
            current_sentence += char
            
            # 检查主要结束符
            if char in main_endings:
                if len(current_sentence.strip()) >= 2:
                    sentences.append(current_sentence.strip())
                    current_sentence = ""
            
            # 检查次要结束符
            elif char in minor_endings and len(current_sentence) >= 8:
                if len(current_sentence.strip()) >= 4:
                    sentences.append(current_sentence.strip())
                    current_sentence = ""
        
        # 处理剩余文本
        if current_sentence.strip():
            if len(current_sentence.strip()) >= 1:
                sentences.append(current_sentence.strip())
            elif sentences:
                sentences[-1] += current_sentence.strip()
        
        # 如果没有分割出句子，返回原文本
        if not sentences:
            sentences = [text.strip()]
        
        # 过滤空句子
        sentences = [s for s in sentences if s.strip()]
        
        return sentences
    
    def _is_abbreviation(self, text: str, pos: int) -> bool:
        """检查句号是否在缩写中"""
        if pos == 0 or pos >= len(text) - 1:
            return False
        
        # 检查前一个字符是否为字母
        prev_char = text[pos - 1]
        if not prev_char.isalpha():
            return False
        
        # 检查后一个字符是否为空格或句子结束
        next_char = text[pos + 1] if pos + 1 < len(text) else ' '
        if next_char not in [' ', '\n', '\t', '.', '!', '?']:
            return False
        
        # 检查是否为常见缩写
        abbrev_start = max(0, pos - 3)
        abbrev_text = text[abbrev_start:pos + 1].lower()
        common_abbrevs = ['mr.', 'dr.', 'prof.', 'etc.', 'vs.', 'inc.', 'ltd.', 'corp.']
        
        return any(abbrev_text.endswith(abbrev) for abbrev in common_abbrevs)
    
    def _find_best_split_point(self, text: str, max_length: int) -> int:
        """找到最佳的分割点"""
        # 优先在空格处分割
        last_space = text.rfind(' ', 0, max_length)
        if last_space > max_length * 0.6:  # 如果空格位置合理
            return last_space
        
        # 其次在逗号处分割
        last_comma = text.rfind(',', 0, max_length)
        if last_comma > max_length * 0.6:
            return last_comma + 1
        
        # 再次在分号处分割
        last_semicolon = text.rfind(';', 0, max_length)
        if last_semicolon > max_length * 0.6:
            return last_semicolon + 1
        
        # 最后在冒号处分割
        last_colon = text.rfind(':', 0, max_length)
        if last_colon > max_length * 0.6:
            return last_colon + 1
        
        # 如果都没有合适的，返回0表示无法分割
        return 0
    
    def _force_split_long_sentence(self, sentence: str) -> list:
        """强制分割过长的句子，优化TTS处理"""
        max_length = 50  # 进一步减少长度，提高TTS响应速度
        sentences = []
        
        words = sentence.split()
        current_sentence = ""
        
        for word in words:
            # 检查添加单词后是否超过长度限制
            test_sentence = current_sentence + (" " + word if current_sentence else word)
            
            if len(test_sentence) <= max_length:
                current_sentence = test_sentence
            else:
                # 如果当前句子不为空，保存它
                if current_sentence:
                    sentences.append(current_sentence)
                # 开始新句子
                current_sentence = word
                
                # 如果单个单词就超过长度限制，强制分割
                if len(word) > max_length:
                    # 按字符强制分割
                    while len(word) > max_length:
                        sentences.append(word[:max_length])
                        word = word[max_length:]
                    current_sentence = word
        
        # 添加最后一个句子
        if current_sentence:
            sentences.append(current_sentence)
        
        return sentences
    
    async def _async_stream_processor(self, llm_stream: AsyncGenerator[str, None], current_gen_id: int):
        """完全异步的流式处理器 - 不阻塞LLM输出"""
        is_first_sentence = True
        tts_tasks = []
        
        try:
            # 流式处理：边接收边处理，不等待完整文本
            accumulated_text = ""
            buffer_size = 5  # 更小的缓冲区，更快响应
            
            async for chunk in llm_stream:
                # 检查代际是否过时
                if not self.queue_manager.is_generation_current(current_gen_id):
                    print(f"\n[系统] 代际 {current_gen_id} 已过时，终止任务。")
                    return
                
                # 检查停止事件
                if self.stop_event.is_set(): 
                    print(f"\n[系统] TTS处理被中断，终止任务。")
                    break
                
                accumulated_text += chunk
                
                # 流式句子检测：当缓冲区达到一定大小或遇到句子结束符时处理
                if len(accumulated_text) >= buffer_size or any(char in accumulated_text for char in ['。', '！', '？', '.', '，', '；', '：']):
                    # 尝试提取完整句子
                    sentences = self._smart_sentence_split(accumulated_text)
                    
                    # 处理除最后一个句子外的所有句子（最后一个可能不完整）
                    for sentence in sentences[:-1]:
                        # 创建异步TTS任务，不等待完成
                        tts_task = asyncio.create_task(
                            self._process_single_sentence_async(sentence, current_gen_id, is_first_sentence)
                        )
                        tts_tasks.append(tts_task)
                        
                        if is_first_sentence:
                            is_first_sentence = False
                    
                    # 保留最后一个可能不完整的句子
                    accumulated_text = sentences[-1] if sentences else ""
            
            # 处理剩余的文本
            if accumulated_text.strip():
                tts_task = asyncio.create_task(
                    self._process_single_sentence_async(accumulated_text, current_gen_id, is_first_sentence)
                )
                tts_tasks.append(tts_task)
            
            # 不等待TTS任务完成，让它们异步运行
            # 如果需要等待，可以在这里添加：await asyncio.gather(*tts_tasks, return_exceptions=True)
                        
        finally:
            self.audio_player.put_audio_chunk(None)
    
    async def _simple_stream_processor(self, llm_stream: AsyncGenerator[str, None], current_gen_id: int):
        """简化的流式处理器 - 确保不阻塞LLM输出，处理所有文本"""
        is_first_sentence = True
        
        try:
            # 流式处理：边接收边处理，不等待完整文本
            accumulated_text = ""
            buffer_size = 8  # 减少缓冲区大小，更快处理
            
            async for chunk in llm_stream:
                # 检查代际是否过时
                if not self.queue_manager.is_generation_current(current_gen_id):
                    print(f"\n[系统] 代际 {current_gen_id} 已过时，终止任务。")
                    return
                
                # 检查停止事件
                if self.stop_event.is_set(): 
                    print(f"\n[系统] TTS处理被中断，终止任务。")
                    break
                
                accumulated_text += chunk
                
                # 流式句子检测：当缓冲区达到一定大小或遇到句子结束符时处理
                if len(accumulated_text) >= buffer_size or any(char in accumulated_text for char in ['。', '！', '？', '.', '，', '；', '：']):
                    # 尝试提取完整句子
                    sentences = self._smart_sentence_split(accumulated_text)
                    
                    # 处理除最后一个句子外的所有句子（最后一个可能不完整）
                    for sentence in sentences[:-1]:
                        if sentence.strip():  # 确保句子不为空
                            # 直接处理句子，不使用复杂的异步任务
                            await self._process_single_sentence(sentence, current_gen_id, is_first_sentence)
                            if is_first_sentence:
                                is_first_sentence = False
                    
                    # 保留最后一个可能不完整的句子
                    accumulated_text = sentences[-1] if sentences else ""
            
            # 处理剩余的文本 - 这是关键，确保所有文本都被处理
            if accumulated_text.strip():
                print(f"\n[TTS] 处理剩余文本: {accumulated_text[:50]}...")
                await self._process_single_sentence(accumulated_text, current_gen_id, is_first_sentence)
                        
        finally:
            self.audio_player.put_audio_chunk(None)
    
    def _llm_and_tts_producer(self, llm_stream: AsyncGenerator[str, None], current_gen_id: int):
        """生产者线程：获取LLM句子，转换为TTS音频，放入队列 - 兼容性方法"""
        is_first_sentence = True
        
        try:
            async def process_stream():
                nonlocal is_first_sentence
                
                # 流式处理优化：边接收边处理，不等待完整文本
                accumulated_text = ""
                buffer_size = 8  # 减少缓冲区大小，更快处理首句
                
                async for chunk in llm_stream:
                    # 检查代际是否过时
                    if not self.queue_manager.is_generation_current(current_gen_id):
                        print(f"\n[系统] 代际 {current_gen_id} 已过时，终止任务。")
                        return
                    
                    # 更频繁地检查停止事件
                    if self.stop_event.is_set(): 
                        print(f"\n[系统] TTS处理被中断，终止任务。")
                        break
                    
                    accumulated_text += chunk
                    
                    # 流式句子检测：当缓冲区达到一定大小或遇到句子结束符时处理
                    if len(accumulated_text) >= buffer_size or any(char in accumulated_text for char in ['。', '！', '？', '.', '，', '；', '：']):
                        # 尝试提取完整句子
                        sentences = self._smart_sentence_split(accumulated_text)
                        
                        # 处理除最后一个句子外的所有句子（最后一个可能不完整）
                        for sentence in sentences[:-1]:
                            await self._process_single_sentence(sentence, current_gen_id, is_first_sentence)
                            if is_first_sentence:
                                is_first_sentence = False
                        
                        # 保留最后一个可能不完整的句子
                        accumulated_text = sentences[-1] if sentences else ""
                
                # 处理剩余的文本
                if accumulated_text.strip():
                    await self._process_single_sentence(accumulated_text, current_gen_id, is_first_sentence)
            
            # 运行异步流处理
            asyncio.run(process_stream())
                        
        finally:
            self.audio_player.put_audio_chunk(None)
    
    async def _process_single_sentence_async(self, sentence: str, current_gen_id: int, is_first_sentence: bool):
        """异步处理单个句子 - 使用executor避免阻塞"""
        # 如果TTS不可用，直接跳过TTS处理
        if not self.is_tts_available:
            return
            
        # 检查代际是否过时
        if not self.queue_manager.is_generation_current(current_gen_id):
            print(f"\n[系统] 代际 {current_gen_id} 已过时，终止任务。")
            return
        
        if self.stop_event.is_set(): 
            return
        
        # 记录第一个句子的时间
        if is_first_sentence and self.user_input_time > 0:
            self.llm_first_sentence_time = time.time()
        
        # 清理文本，去除表情符号和特殊字符
        cleaned_sentence = self._clean_text_for_tts(sentence)
        
        # 检查清理后的文本是否有效
        if not cleaned_sentence or len(cleaned_sentence.strip()) < 2:
            print(f"\n[TTS] 跳过无效文本: '{sentence[:20]}...' -> '{cleaned_sentence}'")
            return
            
        if cleaned_sentence.startswith(('错误', 'API', '异常', '警告')):
            print(f"\n❌ LLM 响应异常/错误: {cleaned_sentence}")
            return

        # 使用executor异步处理TTS合成，避免阻塞主线程
        try:
            loop = asyncio.get_running_loop()
            await loop.run_in_executor(
                None, 
                self._sync_tts_processing, 
                cleaned_sentence, 
                current_gen_id, 
                is_first_sentence
            )
        except Exception as e:
            print(f"\n[TTS] 异步处理句子时出错: {e}")
    
    def _sync_tts_processing(self, cleaned_sentence: str, current_gen_id: int, is_first_sentence: bool):
        """同步TTS处理，在executor中运行"""
        try:
            # TTS合成
            for audio_chunk in self.tts_client.get_tts_audio_stream(
                cleaned_sentence, 
                self.config["TTS_PARAMS"], 
                self.config["CHUNK_SIZE"],
                self.stop_event
            ):
                # 检查代际是否过时
                if not self.queue_manager.is_generation_current(current_gen_id):
                    print(f"\n[系统] 代际 {current_gen_id} 在TTS中过时，终止。")
                    return
                
                # 检查停止事件
                if self.stop_event.is_set(): 
                    print(f"\n[系统] TTS音频流被中断，终止。")
                    break
                
                # 延迟测量
                if self.llm_first_sentence_time > 0 and self.user_input_time > 0:
                    first_chunk_received_time = time.time()
                    
                    llm_time = self.llm_first_sentence_time - self.user_input_time
                    tts_time = first_chunk_received_time - self.llm_first_sentence_time
                    total_latency = first_chunk_received_time - self.user_input_time
                    
                    print(f"\n[延迟度量] T0->T1 (LLM Time): {llm_time:.3f} 秒 (LLM生成首句)")
                    print(f"[延迟度量] T1->T2 (TTS Time): {tts_time:.3f} 秒 (TTS合成+传输首块)")
                    print(f"[延迟度量] T0->T2 (总延迟): {total_latency:.3f} 秒")

                    # 避免重复打印，并重置时间戳
                    self.user_input_time = 0
                    self.llm_first_sentence_time = 0
                
                self.audio_player.put_audio_chunk(audio_chunk)
                
        except Exception as e:
            print(f"\n[TTS] 同步处理句子时出错: {e}")
    
    async def _process_single_sentence(self, sentence: str, current_gen_id: int, is_first_sentence: bool):
        """处理单个句子 - 简化版本，直接处理"""
        # 如果TTS不可用，直接跳过TTS处理
        if not self.is_tts_available:
            return
            
        # 检查代际是否过时
        if not self.queue_manager.is_generation_current(current_gen_id):
            print(f"\n[系统] 代际 {current_gen_id} 已过时，终止任务。")
            return
        
        if self.stop_event.is_set(): 
            return
        
        # 记录第一个句子的时间
        if is_first_sentence and self.user_input_time > 0:
            self.llm_first_sentence_time = time.time()
        
        # 清理文本，去除表情符号和特殊字符
        cleaned_sentence = self._clean_text_for_tts(sentence)
        
        # 检查清理后的文本是否有效
        if not cleaned_sentence or len(cleaned_sentence.strip()) < 2:
            print(f"\n[TTS] 跳过无效文本: '{sentence[:20]}...' -> '{cleaned_sentence}'")
            return
            
        if cleaned_sentence.startswith(('错误', 'API', '异常', '警告')):
            print(f"\n❌ LLM 响应异常/错误: {cleaned_sentence}")
            return

        # 添加调试信息
        print(f"\n[TTS] 开始处理句子: {cleaned_sentence[:30]}...")

        # 直接处理TTS合成，不使用executor
        try:
            # TTS合成
            for audio_chunk in self.tts_client.get_tts_audio_stream(
                cleaned_sentence, 
                self.config["TTS_PARAMS"], 
                self.config["CHUNK_SIZE"],
                self.stop_event
            ):
                # 检查代际是否过时
                if not self.queue_manager.is_generation_current(current_gen_id):
                    print(f"\n[系统] 代际 {current_gen_id} 在TTS中过时，终止。")
                    return
                
                # 检查停止事件
                if self.stop_event.is_set(): 
                    print(f"\n[系统] TTS音频流被中断，终止。")
                    break
                
                # 延迟测量
                if self.llm_first_sentence_time > 0 and self.user_input_time > 0:
                    first_chunk_received_time = time.time()
                    
                    llm_time = self.llm_first_sentence_time - self.user_input_time
                    tts_time = first_chunk_received_time - self.llm_first_sentence_time
                    total_latency = first_chunk_received_time - self.user_input_time
                    
                    print(f"\n[延迟度量] T0->T1 (LLM Time): {llm_time:.3f} 秒 (LLM生成首句)")
                    print(f"[延迟度量] T1->T2 (TTS Time): {tts_time:.3f} 秒 (TTS合成+传输首块)")
                    print(f"[延迟度量] T0->T2 (总延迟): {total_latency:.3f} 秒")

                    # 避免重复打印，并重置时间戳
                    self.user_input_time = 0
                    self.llm_first_sentence_time = 0
                
                self.audio_player.put_audio_chunk(audio_chunk)
            
            print(f"\n[TTS] 句子处理完成: {cleaned_sentence[:30]}...")
                
        except Exception as e:
            print(f"\n[TTS] 处理句子时出错: {e}")
    
    async def process_text_async(self, text: str):
        """
        异步处理完整文本 - 最简单的方式，不阻塞LLM输出
        """
        if not self.is_tts_available or not text.strip():
            return
            
        if self.is_processing:
            self._interrupt_and_prepare_new_task()
            
        self.is_processing = True
        
        # 启动音频播放线程
        self.audio_player.start()
        
        # 准备新任务
        current_gen_id = self._interrupt_and_prepare_new_task()
        
        try:
            # 直接处理完整文本，不使用流式处理
            await self._process_complete_text(text, current_gen_id)
        finally:
            self.is_processing = False
    
    async def _process_complete_text(self, text: str, current_gen_id: int):
        """处理完整文本"""
        # 分割成句子
        sentences = self._smart_sentence_split(text)
        
        for i, sentence in enumerate(sentences):
            if not sentence.strip():
                continue
                
            # 检查代际是否过时
            if not self.queue_manager.is_generation_current(current_gen_id):
                print(f"\n[系统] 代际 {current_gen_id} 已过时，终止任务。")
                return
            
            # 检查停止事件
            if self.stop_event.is_set(): 
                print(f"\n[系统] TTS处理被中断，终止任务。")
                break
            
            # 异步处理每个句子
            await self._process_single_sentence_async(sentence, current_gen_id, i == 0)
    
    async def process_realtime_stream_async(self, llm_stream: AsyncGenerator[str, None]):
        """
        完全异步的实时流式处理 - 不阻塞LLM输出
        """
        # 如果TTS不可用，直接跳过TTS处理
        if not self.is_tts_available:
            # 只消费LLM流，不进行TTS处理
            async for chunk in llm_stream:
                pass
            return
            
        if self.is_processing:
            self._interrupt_and_prepare_new_task()
            
        self.is_processing = True
        
        # 启动音频播放线程
        self.audio_player.start()
        
        # 准备新任务
        current_gen_id = self._interrupt_and_prepare_new_task()
        
        try:
            # 使用完全异步的处理方式
            await self._async_stream_processor(llm_stream, current_gen_id)
        finally:
            self.is_processing = False
    
    async def process_realtime_stream(self, llm_stream: AsyncGenerator[str, None]):
        """
        实时处理LLM流式输出 - 简化版本，确保不阻塞LLM输出
        """
        # 如果TTS不可用，直接跳过TTS处理
        if not self.is_tts_available:
            # 只消费LLM流，不进行TTS处理
            async for chunk in llm_stream:
                pass
            return
            
        if self.is_processing:
            self._interrupt_and_prepare_new_task()
            
        self.is_processing = True
        
        # 启动音频播放线程
        self.audio_player.start()
        
        # 准备新任务
        current_gen_id = self._interrupt_and_prepare_new_task()
        
        try:
            # 简化的流式处理，直接处理而不使用复杂的异步任务
            await self._simple_stream_processor(llm_stream, current_gen_id)
        finally:
            self.is_processing = False
    
    async def wait_for_completion(self):
        """等待处理完成"""
        if self.is_tts_available and self.audio_player.player_thread and self.audio_player.player_thread.is_alive():
            loop = asyncio.get_running_loop()
            await loop.run_in_executor(None, lambda: self.audio_player.player_thread.join(timeout=5))
    
    def cleanup(self):
        """清理资源"""
        if self.is_tts_available:
            self.audio_player.stop()


# 兼容性函数，保持向后兼容
def switch_models(api_host: str, gpt_path: str, sovits_path: str) -> bool:
    """通过 API 接口切换 GPT 和 SoVITS 模型权重"""
    client = TTSClient(api_host, "", f"{api_host}/control")
    return client.switch_models(gpt_path, sovits_path)


def preload_tts(api_url: str, params: dict, preload_text: str):
    """通过一个简短的合成请求来预热模型"""
    # 从URL提取API主机
    api_host = api_url.split('/tts')[0] if '/tts' in api_url else api_url
    client = TTSClient(api_host, api_url, f"{api_host}/control")
    return client.preload_tts(params, preload_text)
